// VirtualMachine.h
#include <iostream>
#include <string>
#include <utility>
#include <cstdio>
#include <chrono>  // 包含chrono库

#include <vector>
#include <functional>
#include <queue>
#include <sstream>
#include <bits/unique_ptr.h>
#include "Readini.h"

using namespace std;



#define AX_SIZE 1000000  // 减少默认值

/**
 * 声明VM结构体
 */
struct VM {
    std::unique_ptr<string[]> sax;
    std::unique_ptr<int[]> iax;
    std::unique_ptr<float[]> fax;
    std::unique_ptr<double[]> dax;
    std::unique_ptr<char[]> cax;
    std::unique_ptr<bool[]> bax;
    std::unique_ptr<void*[]> ax;
    int ax_size = AX_SIZE;
    std::unique_ptr<double[]> registers;
    int register_count = 100;  // Number of registers
    int pointer_count;
    int current_pointer_count = 0;  // 新增指针计数器
    std::vector<double> stack;  // 新增栈
    std::function<void()> for_callback;  // 新增回调函数
    std::unique_ptr<std::queue<string>> for_commands;  // 新增指令队列
    int for_loop_count = 0;  // 新增计数器
    std::function<void()> while_callback;  // 新增回调函数
};

struct FLAGS{
    string status;
};

class VirtualMachineMain {

public:

    enum INSTRUCTIONS {
        ADD, SUB, DIV, MUL, MOV, POP, PUSH, CMP, FOR, RET, JMP, ERROR_FLAG,
        IAX, FAX, DAX, SAX, BAX, EMPTY, CAX, LESS, GREATER, EQUAL, NOTEQUAL, AND, OR, NOT,
        WHILE,

        // <  >
        VARIABLE, CONSTANT, LEFT, RIGHT, POINT
    };

    static FLAGS* flags;

    static VM* vm;
    /**
     * 初始化虚拟机
     */
    static void init() {
        // 确保 vm 已经初始化
        if (vm == nullptr) {
            vm = new VM();
        }

        ReadInI reader;
        string filename = "SVM.ini";
        string section = "VirtualMachineConfig";
        string key = "POINTER_COUNT";

        string value = reader.GetConfigContents(filename, section, key);

        int pointer_count = 0;
        try {
            pointer_count = stoi(value);  // 将字符串转换为整数
        } catch (const invalid_argument& e) {
            cerr << "Error: Invalid value for POINTER_COUNT in config file. Using default value 0." << endl;
            pointer_count = 0;  // 设置默认值
        }
        // 根据 pointer_count 自动确定 AX_SIZE
        int ax_size = 100 * AX_SIZE;  // 设置最大允许值

        if (pointer_count > 100) {
            ax_size = 10 * AX_SIZE;  // 如果 pointer_count 大于 100，则将 AX_SIZE 增加一倍
        } else if (pointer_count > 50) {
            ax_size = 6.8 * AX_SIZE;  // 如果 pointer_count 大于 50，则将 AX_SIZE 增加 50%
        }


        vm->pointer_count = pointer_count;  // 设置 vm->pointer_count
        vm->ax_size = ax_size;  // 设置 vm->ax_size

        // 动态分配内存
        vm->sax = std::make_unique<string[]>(vm->ax_size);
        vm->iax = std::make_unique<int[]>(vm->ax_size);
        vm->fax = std::make_unique<float[]>(vm->ax_size);
        vm->dax = std::make_unique<double[]>(vm->ax_size);
        vm->cax = std::make_unique<char[]>(vm->ax_size);
        vm->bax = std::make_unique<bool[]>(vm->ax_size);
        vm->ax = std::make_unique<void*[]>(vm->ax_size);
        vm->registers = std::make_unique<double[]>(vm->register_count);
        vm->for_commands = std::make_unique<std::queue<std::string>>();
    }

    static double getRegister(int index) {
        if (vm == nullptr) {
            cerr << "Error: VM is not initialized." << endl;
            return 0;
        }
        if (index >= 0 && index < vm->register_count) {
            return vm->registers[index];
        } else {
            cout << "[SVM EXCEPTION!]: Invalid register index" << endl;
            return 0;
        }
    }

    /**
     * 指令枚举
     * @param instruction
     * @return
     */
    static INSTRUCTIONS instructions(const string &instruction) {
        if (instruction == "ADD") {
            return ADD;
        } else if (instruction == "SUB") {
            return SUB;
        } else if (instruction == "DIV") {
            return DIV;
        } else if (instruction == "MUL") {
            return MUL;
        } else if (instruction == "MOV") {
            return MOV;
        } else if (instruction == "POP") {
            return POP;
        } else if (instruction == "PUSH") {
            return PUSH;
        } else if (instruction == "CMP") {
            return CMP;
        } else if (instruction == "FOR") {
            return FOR;
        } else if (instruction == "RET") {
            return RET;
        } else if (instruction == "JMP") {
            return JMP;
        } else if (instruction == "IAX") {
            return IAX;
        } else if (instruction == "CAX") {
            return CAX;
        } else if (instruction == "SAX") {
            return SAX;
        } else if (instruction == "FAX") {
            return FAX;
        } else if (instruction == "BAX") {
            return BAX;
        } else if (instruction == "DAX") {
            return DAX;
        } else if (instruction == "EMPTY") {
            return EMPTY;
        } else if (instruction == "LESS") {
            return LESS;
        } else if (instruction == "GREATER") {
            return GREATER;
        } else if (instruction == "EQUAL") {
            return EQUAL;
        } else if (instruction == "NOTEQUAL") {
            return NOTEQUAL;
        } else if (instruction == "AND") {
            return AND;
        } else if (instruction == "OR") {
            return OR;
        } else if (instruction == "NOT") {
            return NOT;
        } else if (instruction == "WHILE") {
            return WHILE;
        }  else if (instruction == "VARIABLE") {
            return VARIABLE;
        } else if (instruction == "CONSTANT") {
            return CONSTANT;
        } else if (instruction == "LEFT") {
            return LEFT;
        } else if (instruction == "RIGHT") {
            return RIGHT;
        } else if (instruction == "POINT:") {
            return POINT;
        } else {
            return ERROR_FLAG;
        }
    }

    /**
     * 执行基本运算符
     * @param instruction
     * @param a
     * @param b
     * @param reg_index
     */
    static void execute(const string &instruction, double a, double b, int reg_index) {
        double result = 0;
        switch (instructions(instruction)) {
            case ADD:
                result = add(a, b);
                break;
            case SUB:
                result = sub(a, b);
                break;
            case DIV:
                result = div(a, b);
                break;
            case MUL:
                result = mul(a, b);
                break;
            case LESS:
                if (result = (a < b) ? 1.0 : 0.0){
                } else {
                    cout << "Error: Cannot Match Value!";
                }
                break;
            case GREATER:
                if (result = (a < b) ? 1.0 : 0.0){
                } else {
                    cout << "Error: Cannot Match Value!";
                }
                break;
            case EQUAL:
                if (result = (a == b) ? 1.0 : 0.0){
                } else {
                    cout << "Error: Cannot Match Value!";
                }
                break;
            case NOTEQUAL:
                if (result = (a != b) ? 1.0 : 0.0){
                } else {
                    cout << "Error: Cannot Match Value!";
                }
                break;
            case AND:
                if (result = (a != 0.0 && b != 0.0) ? 1.0 : 0.0)
                {
                } else {
                    cout << "Error: Cannot Match Value!";
                }
                break;
            case OR:
                if (result = (a != 0.0 || b != 0.0) ? 1.0 : 0.0)
                {
                } else {
                    cout << "Error: Cannot Match Value!";
                }
                break;
            case NOT:
                if (result = (a == 0.0) ? 1.0 : 0.0)
                {
                } else {
                    cout << "Error: Cannot Match Value!";
                }
                break;
            default:
                cout << "Error: Unknown instruction" << endl;
                return;
        }
        setRegister(reg_index, result);
    }

    /**
     * for循环实现
     * @param expr
     * @param callback
     */
    static void for_loop(string expr, std::function<void()> callback) {
        vm->for_loop_count++;  // 增加计数器

        // 使用 stringstream 解析表达式
        stringstream ss(expr);
        string token;
        vector<string> tokens;

        while (getline(ss, token, ' ')) {
            tokens.push_back(token);
        }

        if (tokens.size() < 7) {
            cerr << "Error: Invalid FOR expression format." << endl;
            return;
        }

        // 解析初始条件、终止条件、步长和指令
        int init_reg = stoi(tokens[1]);
        double init_value = stod(tokens[2]);
        string condition = tokens[3];
        int term_reg = stoi(tokens[4]);
        double term_value = stod(tokens[5]);
        double step = 1.0;  // 默认步长为1
        vector<string> commands(tokens.begin() + 6, tokens.end());

        // 设置初始值
        setRegister(init_reg, init_value);

        // 循环执行
        int loop_count = 0;  // 记录循环次数
        while (true) {
            // 检查条件
            double current_value = getRegister(init_reg);
            bool loop_condition = false;

            switch (instructions(condition)) {
                case LESS:
                    loop_condition = (current_value < term_value);
                    break;
                case GREATER:
                    loop_condition = (current_value > term_value);
                    break;
                case EQUAL:
                    loop_condition = (current_value == term_value);
                    break;
                case NOTEQUAL:
                    loop_condition = (current_value != term_value);
                    break;
                default:
                    cerr << "Error: Unknown condition in FOR expression." << endl;
                    return;
            }

            if (!loop_condition) {
                break;
            }

            // 执行指令
            for (const string& command : commands) {
                switch (instructions(command)) {
                    case ADD:
                        execute("ADD", getRegister(init_reg), step, init_reg);  // 增加步长
                        break;
                    case SUB:
                        execute("SUB", getRegister(init_reg), step, init_reg);  // 减少步长
                        break;
                    case MUL:
                        execute("MUL", getRegister(init_reg), step, init_reg);  // 乘以步长
                        break;
                    case DIV:
                        execute("DIV", getRegister(init_reg), step, init_reg);  // 除以步长
                        break;
                    default:
                        cout << "Error: Executing Undefined command: " << command << endl;
                        // 这里可以添加更多的指令处理逻辑
                        break;
                }
            }

            loop_count++;  // 增加循环次数
        }

        // 存储回调函数
        vm->for_callback = std::move(callback);

        // 执行回调函数
        if (vm->for_callback) {
            vm->for_callback();
        } else {
            vm->for_callback = nullptr;
        }
    }

    /////////////////////////////////执行WHILE循环/////////////////////////////////////////////////
    static void ExecuteWhileLoop(const string &expr, std::function<void()> callback) {
        // 使用 stringstream 解析表达式
        stringstream ss(expr);
        string token;
        vector<string> tokens;

        while (getline(ss, token, ' ')) {
            tokens.push_back(token);
        }

        if (tokens.size() < 4) {
            cerr << "Error: Invalid WHILE expression format." << endl;
            return;
        }

        // 解析条件和指令
        string condition = tokens[0];
        int reg_index = stoi(tokens[1]);
        double term_value = stod(tokens[2]);
        vector<string> commands(tokens.begin() + 3, tokens.end());

        // 循环执行
        while (true) {
            // 检查条件
            double current_value = getRegister(reg_index);
            bool loop_condition = false;

            switch (instructions(condition)) {
                case LESS:
                    loop_condition = (current_value < term_value);
                    break;
                case GREATER:
                    loop_condition = (current_value > term_value);
                    break;
                case EQUAL:
                    loop_condition = (current_value == term_value);
                    break;
                case NOTEQUAL:
                    loop_condition = (current_value != term_value);
                    break;
                default:
                    cerr << "Error: Unknown condition in WHILE expression." << endl;
                    return;
            }


            if (!loop_condition) {
                break;
            }

            // 执行指令
            for (const string& command : commands) {
                switch (instructions(command)) {
                    case ADD:
                        execute("ADD", getRegister(reg_index), 1.0, reg_index);  // 增加步长
                        break;
                    case SUB:
                        execute("SUB", getRegister(reg_index), 1.0, reg_index);  // 减少步长
                        break;
                    case MUL:
                        execute("MUL", getRegister(reg_index), 2.0, reg_index);  // 乘以步长
                        break;
                    case DIV:
                        execute("DIV", getRegister(reg_index), 2.0, reg_index);  // 除以步长
                        break;
                    default:
                        cout << "Error: Executing undefined command: " << command << endl;
                        // 这里可以添加更多的指令处理逻辑
                        break;
                }
            }
        }

        // 存储回调函数
        vm->while_callback = std::move(callback);

        // 执行回调函数
        if (vm->while_callback) {
            vm->while_callback();
        } else {
            vm->while_callback = nullptr;
        }
    }

    /**
     * 赋值
     * @param mode
     * @param value
     * @param type
     */
   static void SetValue(void *value, const string &type) {
    if (type == " ") {
        // 自动解析值
        string type_name = typeid(value).name();
        if (type_name == "i") {
            vm->iax[0] = *(int*)value;
        } else if (type_name == "d") {
            vm->dax[0] = *(double*)value;
        } else if (type_name == "c") {
            vm->cax[0] = *(char*)value;
        } else if (type_name == "b") {
            vm->bax[0] = *(bool*)value;
        } else if (type_name == "s") {
            vm->sax[0] = *(string*)value;
        } else if (type_name == "f") {
            vm->fax[0] = *(float*)value;
        } else if (type_name == "Pv") {
            // 使用 reset 方法重置 unique_ptr
            vm->ax.reset(new void*[AX_SIZE]);
            for (size_t i = 0; i < AX_SIZE; ++i) {
                vm->ax[i] = nullptr;
            }
            vm->ax[0] = value;
        } else {
            cout << "[SVM EXCEPTION!]: Unknown type" << endl;
        }
    } else {
        if (type == "INT") {
            vm->iax[0] = *(int *) value;
        } else if (type == "DOUBLE") {
            vm->dax[0] = *(double *) value;
        } else if (type == "CHAR") {
            vm->cax[0] = *(char *) value;
        } else if (type == "BOOLEAN") {
            vm->bax[0] = *(bool *) value;
        } else if (type == "STRING") {
            vm->sax[0] = *(string *) value;
        } else if (type == "FLOAT") {
            vm->fax[0] = *(float *) value;
        } else if (type == "EMPTY") {
            // 使用 reset 方法重置 unique_ptr
            vm->ax.reset(new void*[AX_SIZE]);
            for (size_t i = 0; i < AX_SIZE; ++i) {
                vm->ax[i] = nullptr;
            }
            vm->ax[0] = value;
        } else {
            cout << "[SVM EXCEPTION!]: Unknown type" << endl;
        }
    }
}
    /**
     * 设置寄存器
     * @param index
     * @param value
     */
    static void setRegister(int index, double value) {
        if (vm == nullptr) {
            cerr << "Error: VM is not initialized." << endl;
            return;
        }
        if (index >= 0 && index < vm->register_count) {
            vm->registers[index] = value;
        } else {
            cout << "[SVM EXCEPTION!]: Invalid register index" << endl;
        }
    }

    // 私有寄存器操作
    static void push(void *value) {
        vm->stack.push_back(*static_cast<double*>(value));
    }

    static void cmp(void *value) {
        double valueToCompare = *static_cast<double*>(value);
        if (!vm->stack.empty()) {
            double topValue = vm->stack.back();
            if (topValue == valueToCompare) {
                vm->bax[0] = true;
            } else {
                vm->bax[0] = false;
            }
        } else {
            cout << "[SVM EXCEPTION!]: Stack is empty, couldn't find value" << vm->stack.size() << endl;
        }
    }


private:

    /**
     * 基本的逻辑运算
     * @param a
     * @param b
     * @return
     */
    static double add(double a, double b) {
        vm->iax[0] = a + b;
    }

    static double sub(double a, double b) {
        vm->iax[0] = a - b;
    }

    static double div(double a, double b) {
        if (b == 0) {
            cout << "Error: Division by zero" << endl;
            return 0;
        }
        vm->iax[0] = a / b;
    }

    static double mul(double a, double b) {
        vm->iax[0] = a * b;
    }

public:

    /**
     * 公有的高级操作
     * @param type
     * @param value
     * @return
     */
    static void* DataTypeImpl(const string &type, const void* value) {
        if (vm->current_pointer_count >= vm->pointer_count) {
            cout << "Error: Maximum pointer count exceeded." << endl;
            return nullptr;
        }

        void* result = nullptr;

        if (type == "FLOAT") {
            vm->fax[vm->current_pointer_count] = *static_cast<const float*>(value);
            result = &vm->fax[vm->current_pointer_count];
        } else if (type == "DOUBLE") {
            vm->dax[vm->current_pointer_count] = *static_cast<const double*>(value);
            result = &vm->dax[vm->current_pointer_count];
        } else if (type == "INT") {
            vm->iax[vm->current_pointer_count] = *static_cast<const int*>(value);
            result = &vm->iax[vm->current_pointer_count];
        } else if (type == "STRING") {
            vm->sax[vm->current_pointer_count] = *static_cast<const string*>(value);
            result = &vm->sax[vm->current_pointer_count];
        } else if (type == "CHAR") {
            vm->cax[vm->current_pointer_count] = *static_cast<const char*>(value);
            result = &vm->cax[vm->current_pointer_count];
        } else if (type == "EMPTY") {
            // 使用 reset 方法重置 unique_ptr
            vm->ax.reset(new void*[AX_SIZE]);
            for (size_t i = 0; i < AX_SIZE; ++i) {
                vm->ax[i] = nullptr;
            }
            vm->ax[vm->current_pointer_count] = const_cast<void*>(value);
            result = vm->ax[vm->current_pointer_count];
        } else if (type == "BOOLEAN") {
            vm->bax[vm->current_pointer_count] = *static_cast<const bool*>(value);
            result = &vm->bax[vm->current_pointer_count];
        } else {
            cout << "Error: Unknown data type" << endl;
            return nullptr;
        }

        if (result != nullptr) {
            vm->current_pointer_count++;
        }

        return result;
    }


    ///////////////////////// 执行高级指令 ///////////////////////////////
    static void ExecuteVirtualMachine_BC(const string &command, const string &registerName, void *value, std::function<void()> callback = nullptr) {
        if (registerName == "IAX") {
            vm->iax[0] = *static_cast<int*>(value);
        } else if (registerName == "CAX") {
            vm->cax[0] = *static_cast<char*>(value);
        } else if (registerName == "SAX") {
            vm->sax[0] = *static_cast<string*>(value);
        } else if (registerName == "FAX") {
            vm->fax[0] = *static_cast<float*>(value);
        } else if (registerName == "DAX") {
            vm->dax[0] = *static_cast<double*>(value);
        } else if (registerName == "BAX") {
            vm->bax[0] = *static_cast<bool*>(value);
        } else if (registerName == "EMPTY") {
            // 使用 reset 方法重置 unique_ptr
            vm->ax.reset(new void*[AX_SIZE]);
            for (size_t i = 0; i < AX_SIZE; ++i) {
                vm->ax[i] = nullptr;
            }
            vm->ax[0] = value;
        }

        switch (instructions(command)) {
            case MOV:
                mov(registerName, value);
                break;
            case POP:
                pop();
                break;
            case PUSH:
                push(value);
                break;
            case CMP:
                cmp(value);
                break;
            case FOR:
                vm->for_callback = std::move(callback);  // 存储回调函数
                break;
            default:
                cout << "Error: Unknown command" << endl;
                break;
        }
    }

    static void ExecuteVirtualMachine_BC_For(const string &command, const string &registerName, void *value, std::function<void()> callback = nullptr) {
        if (registerName == "IAX") {
            vm->iax[0] = *static_cast<int*>(value);
        } else if (registerName == "CAX") {
            vm->cax[0] = *static_cast<char*>(value);
        } else if (registerName == "SAX") {
            vm->sax[0] = *static_cast<string*>(value);
        } else if (registerName == "FAX") {
            vm->fax[0] = *static_cast<float*>(value);
        } else if (registerName == "DAX") {
            vm->dax[0] = *static_cast<double*>(value);
        } else if (registerName == "BAX") {
            vm->bax[0] = *static_cast<bool*>(value);
        } else if (registerName == "EMPTY") {
            // 使用 reset 方法重置 unique_ptr
            vm->ax.reset(new void*[AX_SIZE]);
            for (size_t i = 0; i < AX_SIZE; ++i) {
                vm->ax[i] = nullptr;
            }
            vm->ax[0] = value;
        }

        switch (instructions(command)) {
            case MOV:
                mov(registerName, value);
                break;
            case POP:
                pop();
                break;
            case PUSH:
                push(value);
                break;
            case CMP:
                cmp(value);
                break;
            case FOR:
                vm->for_callback = std::move(callback);  // 存储回调函数
                break;
            default:
                cout << "Error: Unknown command" << endl;
                break;
        }
    }

      static void PrintStack(const std::string &registerName) {
        if (registerName == "IAX") {

            for (size_t i = 0; i < AX_SIZE; ++i) {
                if (vm->iax[i] != 0) { // 假设0表示未使用的值
                    std::cout << vm->iax[i] << std::endl;
                }
            }

        } else if (registerName == "CAX") {
            for (size_t i = 0; i < AX_SIZE; ++i) {
                if (vm->cax[i] != '\0') { // 假设'\0'表示未使用的值
                    std::cout << vm->cax[i] << std::endl;
                }
            }
        } else if (registerName == "SAX") {
            for (size_t i = 0; i < AX_SIZE; ++i) {
                if (!vm->sax[i].empty()) { // 假设空字符串表示未使用的值
                    std::cout << vm->sax[i] << std::endl;
                }
            }
        } else if (registerName == "FAX") {
            for (size_t i = 0; i < AX_SIZE; ++i) {
                if (vm->fax[i] != 0.0f) { // 假设0.0f表示未使用的值
                    std::cout << vm->fax[i] << std::endl;
                }
            }
        } else if (registerName == "DAX") {
            for (size_t i = 0; i < AX_SIZE; ++i) {
                if (vm->dax[i] != 0.0) { // 假设0.0表示未使用的值
                    std::cout<< vm->dax[i] << std::endl;
                }
            }
        } else if (registerName == "BAX") {
            for (size_t i = 0; i < AX_SIZE; ++i) {
                std::cout  << vm->bax[i] << std::endl;
            }
        } else if (registerName == "AX") {
            for (size_t i = 0; i < AX_SIZE; ++i) {
                if (vm->ax[i] != nullptr) {
                    std::cout  << *static_cast<double*>(vm->ax[i]) << std::endl;
                }
            }
        } else {
            std::cout << "Unknown register: " << registerName << std::endl;
        }
    }

private:

    static void mov(const string &registerName, void *value) {
        if (registerName == "IAX") {
            vm->iax[0] = *static_cast<int*>(value);
        } else if (registerName == "CAX") {
            vm->cax[0] = *static_cast<char*>(value);
        } else if (registerName == "SAX") {
            vm->sax[0] = *static_cast<string*>(value);
        } else if (registerName == "FAX") {
            vm->fax[0] = *static_cast<float*>(value);
        } else if (registerName == "DAX") {
            vm->dax[0] = *static_cast<double*>(value);
        } else if (registerName == "BAX") {
            vm->bax[0] = *static_cast<bool*>(value);
        } else if (registerName == "EMPTY") {
            // 使用 reset 方法重置 unique_ptr
            vm->ax.reset(new void*[AX_SIZE]);
            for (size_t i = 0; i < AX_SIZE; ++i) {
                vm->ax[i] = nullptr;
            }
            vm->ax[0] = value;
        }
    }

    static void pop() {
        if (!vm->stack.empty()) {
            vm->stack.pop_back();
        } else {
            cout << "[SVM EXCEPTION!]: Stack underflow" << endl;
        }
    }


};